package com.nt.thah.utils;


import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;

/**
 * Description
 * 对称加密 （des） 加解密工具类
 *
 *
 * @version 1.0
 * @date 2019/12/23 19:59
 */
@Slf4j
public class DESUtils {
    /**
     * 云账户专用key
     */
    private static final String YUN_KEY = "uCz8fN0y1YGgX4iSuOj4a9i1";

    /**
     * Description
     * des加密
     * @param   *
     * @param datasource byte[]
     * @param password String
     *
     * @version 1.0
     * @date 2019/12/23 19:54
     */
    public static byte[] encrypt(byte[] datasource, String password) {
        try{
            SecureRandom random = new SecureRandom();
            DESKeySpec desKey = new DESKeySpec(password.getBytes());
            //创建一个密匙工厂，然后用它把DESKeySpec转换成
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey secureKey = keyFactory.generateSecret(desKey);
            //Cipher对象实际完成加密操作
            Cipher cipher = Cipher.getInstance("DES");
            //用密匙初始化Cipher对象
            cipher.init(Cipher.ENCRYPT_MODE, secureKey, random);
            //现在，获取数据并加密
            //正式执行加密操作
            return cipher.doFinal(datasource);
        }catch(Throwable e){
            log.error("des 加密异常", e);
        }
        return null;
    }
    /**
     * 解密
     * @param src byte[]
     * @param password String
     * @return byte[]
     * @throws Exception
     */
    public static byte[] decrypt(byte[] src, String password) throws Exception {
        // DES算法要求有一个可信任的随机数源
        SecureRandom random = new SecureRandom();
        // 创建一个DESKeySpec对象
        DESKeySpec desKey = new DESKeySpec(password.getBytes());
        // 创建一个密匙工厂
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        // 将DESKeySpec对象转换成SecretKey对象
        SecretKey secureKey = keyFactory.generateSecret(desKey);
        // Cipher对象实际完成解密操作
        Cipher cipher = Cipher.getInstance("DES");
        // 用密匙初始化Cipher对象
        cipher.init(Cipher.DECRYPT_MODE, secureKey, random);
        // 真正开始解密操作
        return cipher.doFinal(src);
    }

    /**
     * Description
     * des加密方法 === > 专用云账户
     * @param  content : 待加密字符串
     *
     * @version 1.0
     * @date 2019/12/23 19:57
     */
    public static String desEncrypt(String content) throws Exception {

        byte[] keys = YUN_KEY.getBytes(StandardCharsets.UTF_8.name());
        byte[] enc = tripleDesEncrypt(content.getBytes(StandardCharsets.UTF_8.name()), keys);
        byte[] enc64 = Base64.encodeBase64(enc);
        return new String(enc64);
    }

    /** 
     * Description  
     * des 加密
     * @param
     *
     * @version 1.0
     * @date 2019/12/23 19:58
     */
    public static byte[] tripleDesEncrypt(byte[] content, byte[] key) throws Exception {
        byte[] icv = new byte[8];
        System.arraycopy(key, 0, icv, 0, 8);
        return tripleDesEncrypt(content, key, icv);
    }
    /** 
     * Description  
     * des 加密
     * @param
     *
     * @version 1.0
     * @date 2019/12/23 19:58
     */
    protected static byte[] tripleDesEncrypt(byte[] content, byte[] key, byte[] icv) throws Exception {
        final SecretKey secretKey = new SecretKeySpec(key, "DESede");
        final Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        final IvParameterSpec iv = new IvParameterSpec(icv);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
        return cipher.doFinal(content);
    }


    /****************************************des 与 android & ios 交互*********************************************/

    private static byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8 };
    /** 
     * Description  
     * des 与 android & ios 交互 - 加密
     *
     * @param
     *
     * @version 1.0
     * @date 2019/12/23 20:01
     */
    public static String encryptDES(String encryptString, String encryptKey)
            throws Exception {
        IvParameterSpec zeroIv = new IvParameterSpec(iv);
        SecretKeySpec key = new SecretKeySpec(encryptKey.getBytes(), "DES");
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
        byte[] encryptedData = cipher.doFinal(encryptString.getBytes());
        return Base64Util.encode(encryptedData);
    }
    /**
     * Description
     * des 与 android & ios 交互 - 解密密
     * @param
     *
     * @version 1.0
     * @date 2019/12/23 20:02
     */
    public static String decryptDES(String decryptString, String decryptKey)
            throws Exception {
        byte[] byteMi = Base64Util.decode(decryptString);
        IvParameterSpec zeroIv = new IvParameterSpec(iv);
        SecretKeySpec key = new SecretKeySpec(decryptKey.getBytes(), "DES");
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);
        byte decryptedData[] = cipher.doFinal(byteMi);
        return new String(decryptedData);
    }

    /**
     * @Description: 金蝶效贷加密
     * @Author ls
     * @Date 2021/06/16 16:48
     */
    public static String xiaoDaiEncrypt(String toEncode, String key, String vector){
        try {
            Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
            DESedeKeySpec dks = new DESedeKeySpec(key.getBytes(), 38);
            SecretKeyFactory keyFactory = SecretKeyFactory
                    .getInstance("DESede");
            SecretKey securekey = keyFactory.generateSecret(dks);
            IvParameterSpec iv = new IvParameterSpec(vector.getBytes(), 0,
                    cipher.getBlockSize());
            cipher.init(1, securekey, iv);
            byte[] encoded = cipher.doFinal(toEncode.getBytes("UTF-8"));
            return Base64Util.encode(encoded);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return null;
    }

    /**
     * @Description: 金蝶效贷解密
     * @Author ls
     * @Date 2021/06/16 16:48
     */
    public static String xiaoDaiDecrypt(String toDecode, String key, String vector) {
        try {
            Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
            DESedeKeySpec dks = new DESedeKeySpec(key.getBytes(), 38);
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
            SecretKey securekey = keyFactory.generateSecret(dks);
            IvParameterSpec iv = new IvParameterSpec(vector.getBytes(), 0,
                    cipher.getBlockSize());
            cipher.init(2, securekey, iv);
            byte[] todecodeBytes = Base64Util.decode(toDecode);
            String decoded = new String(cipher.doFinal(todecodeBytes), "utf-8");
            return decoded;
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return null;
    }
}
